﻿using HtmlAgilityPack;
using ProjectFootball.MVC.Foundation.ResourceLibrary;
using ProjectFootball.MVC.Models.EntityFramework.Entities;
using ProjectFootball.MVC.Models.RepositoryProviders;
using System;
using System.Linq;
using System.Security.Principal;

namespace ProjectFootball.MVC.Foundation
{
    public class BaseImport
    {
        public BaseImport(ImportSite importSite, IRepositoryProvider provider, IPrincipal user)
        {
            this.ImportSite = importSite;
            this.Provider = provider;
            this.User = user;
        }

        protected ImportSite ImportSite;
        protected IRepositoryProvider Provider;
        protected IPrincipal User;

        protected static HtmlDocument GetHtmlDocument(Uri uri)
        {
            HtmlWeb web = new HtmlWeb();
            web.UsingCache = false;

            return web.Load(uri.AbsoluteUri);
        }

        protected LookupCompetition GetLookupCompetition(Guid competitionGuid)
        {
            var query = from l in Provider.LookupCompetitionRepository.Where(l => l.CompetitionGuid == competitionGuid)
                        select l;

            return query.Any() ? query.Single() : null;
        }

        protected Guid ProcessTeam(string siteTeamId, string teamName, Guid countryGuid)
        {
            var lookupTeams = from t in Provider.LookupTeamRepository.Where(t => t.ImportSite == ImportSite && t.SiteTeamId == siteTeamId)
                              select t;

            if (lookupTeams.Any())
                return lookupTeams.FirstOrDefault().TeamGuid;
            else
            {
                Guid teamGuid = Guid.NewGuid();

                Provider.TeamRepository.Add(new Team() 
                { 
                    TeamGuid = teamGuid 
                });

                var teamVersion = new TeamVersion(User, CreateType.Public, Guid.NewGuid(), teamGuid, teamName, countryGuid, null, _DateTime.LowDate, _DateTime.HighDate);
                Provider.TeamVersionRepository.Add(teamVersion);

                Provider.LookupTeamRepository.Add(new LookupTeam()
                {
                    LookupTeamGuid = Guid.NewGuid(),
                    ImportSite = ImportSite,
                    TeamGuid = teamGuid,
                    SiteTeamId = siteTeamId
                });

                Provider.SaveChanges();

                return teamGuid;
            }
            
        }

        protected Guid? ProcessMatch(string siteMatchId, ImportStatus importStatus, DateTime matchDate, Guid? venueGuid, Guid competitionGuid, Guid team1Guid, short? team1Ht, short? team1Ft, Guid team2Guid, short? team2Ht, short? team2Ft)
        {
            var lookupMatches = from m in Provider.LookupMatchRepository
                                where m.ImportSite == ImportSite 
                                && m.SiteMatchId == siteMatchId
                                select m;

            if (lookupMatches.Any())
            {
                var lookupMatch = lookupMatches.Single();

                if (lookupMatch.ImportStatus == ImportStatus.FullDetails)
                    return null;

                lookupMatch.ImportStatus = importStatus;

                Match match = Provider.MatchRepository.Where(m => m.Pk == lookupMatch.MatchGuid).FirstOrDefault();
                match.MatchDate = matchDate;
                match.VenueGuid = venueGuid;
                match.Attendance = null;
                match.Team1HT = team1Ht;
                match.Team1FT = team1Ft;
                match.Team1ETHT = null;
                match.Team1ETFT = null;
                match.Team2HT = team2Ht;
                match.Team2FT = team2Ft;
                match.Team2ETHT = null;
                match.Team2ETFT = null;
                match.IsApproved = User.IsApprover();
                match.AuditUserId = User.GetUserId();
                match.OwnerUserId = User.GetUserId();
                match.AuditTimestamp = DateTime.Now;

                Provider.SaveChanges();

                return lookupMatch.MatchGuid;
            }
            else
            {
                Guid matchGuid = Guid.NewGuid();

                var newMatch = new Match(User, CreateType.Public, Guid.NewGuid(), matchDate, competitionGuid, venueGuid, null, 
                    team1Guid, team1Ht, team1Ft, null, null, null, 
                    team2Guid, team2Ht, team2Ft, null, null, null);

                Provider.MatchRepository.Add(newMatch);

                Provider.LookupMatchRepository.Add(new LookupMatch()
                {
                    LookupMatchGuid = Guid.NewGuid(),
                    ImportSite = ImportSite,
                    MatchGuid = matchGuid,
                    SiteMatchId = siteMatchId,
                    ImportStatus = importStatus
                });

                Provider.SaveChanges();

                return matchGuid;
            }
        }

        protected Guid ProcessPerson(string sitePersonId, string forenames, string surname, DateTime? dob, Guid? countryGuid)
        {
            var lookupPeople = from p in Provider.LookupPersonRepository.Where(p => p.ImportSite == ImportSite && p.SitePersonId == sitePersonId)
                              select p;

            if (lookupPeople.Any())
                return lookupPeople.FirstOrDefault().PersonGuid;
            else
            {
                Guid personGuid = Guid.NewGuid();

                Provider.PersonRepository.Add(new Person()
                {
                    Pk = personGuid,
                    ApprovalGuid = Guid.NewGuid(),
                    Forenames = forenames,
                    Surname = surname,
                    Dob = dob,
                    CountryGuid = countryGuid,
                    ActiveFrom = _DateTime.LowDate,
                    ActiveTo = _DateTime.HighDate,
                    IsApproved = User.IsApprover(),
                    AuditUserId = User.GetUserId(),
                    AuditTimestamp = DateTime.Now
                });

                Provider.LookupPersonRepository.Add(new LookupPerson()
                {
                    LookupPersonGuid = Guid.NewGuid(),
                    ImportSite = ImportSite,
                    PersonGuid = personGuid,
                    SitePersonId = sitePersonId
                });

                Provider.SaveChanges();

                return personGuid;
            }
        }
    }
}